package org.example;

import org.apache.poi.xslf.usermodel.*;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class Main {
    private static final String CONFIG_FILE = "config.properties";
    private static JLabel fileLabel; // 用于显示文件路径的标签
    private static JTextField watermarkTextField; // 用于设置水印内容的输入框
    private static Properties properties = new Properties();

    public static void main(String[] args) {
        loadProperties();
        SwingUtilities.invokeLater(() -> createAndShowGUI());
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("PPT转图片");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 300);

        JButton chooseButton = new JButton("选择文件");
        JButton exportButton = new JButton("导出图片");

        // 创建 PowerPoint 文件过滤器
        FileFilter pptFilter = new FileFilter() {
            @Override
            public boolean accept(File f) {
                return f.isDirectory() || f.getName().toLowerCase().endsWith(".ppt") || f.getName().toLowerCase().endsWith(".pptx");
            }

            @Override
            public String getDescription() {
                return "PowerPoint Files (*.ppt, *.pptx)";
            }
        };

        // 初始化用于显示文件路径的标签
        fileLabel = new JLabel(properties.getProperty("lastSelectedFile", "未选择文件"));
        fileLabel.setHorizontalAlignment(SwingConstants.CENTER);

        // 初始化用于设置水印内容的输入框
        watermarkTextField = new JTextField(properties.getProperty("watermarkContent", "请输入水印内容"), 20);
        watermarkTextField.setHorizontalAlignment(SwingConstants.CENTER);

        chooseButton.addActionListener(e -> {
            File initialDir = new File(properties.getProperty("lastSelectedPath", "D:\\桌面\\PPT兼职"));
            JFileChooser fileChooser;
            if (initialDir.exists() && initialDir.isDirectory()) {
                fileChooser = new JFileChooser(initialDir); // 使用指定的目录
            } else {
                fileChooser = new JFileChooser(); // 使用默认目录
            }
            // 设置文件过滤器
            fileChooser.setFileFilter(pptFilter);
            // 设置默认显示的视图模式为显示详细信息
            fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
            int result = fileChooser.showOpenDialog(frame);
            if (result == JFileChooser.APPROVE_OPTION) {
                File selectedFile = fileChooser.getSelectedFile();
                fileLabel.setText("选择: " + selectedFile.getAbsolutePath()); // 更新标签文本
                saveProperties("lastSelectedFile", selectedFile.getAbsolutePath());
                saveProperties("lastSelectedPath", initialDir.getAbsolutePath());
            }
        });

        exportButton.addActionListener(e -> {
            String filePath = fileLabel.getText().replace("选择: ", "");
            File selectedFile = new File(filePath);
            if (selectedFile.exists() && (selectedFile.getName().toLowerCase().endsWith(".ppt") || selectedFile.getName().toLowerCase().endsWith(".pptx"))) {
                String imgFilePath = selectedFile.getParent() + File.separator;
                String watermark = watermarkTextField.getText(); // 从输入框获取水印内容
                saveProperties("watermarkContent", watermark);
                doPPT2007toImage(selectedFile, imgFilePath, watermark);
                JOptionPane.showMessageDialog(frame, "图片已导出至：" + imgFilePath, "导出成功", JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(frame, "请选择有效的PPT或PPTX文件！", "错误", JOptionPane.ERROR_MESSAGE);
            }
        });

        frame.setLayout(new BorderLayout());
        JPanel buttonPanel = new JPanel(new FlowLayout());
        buttonPanel.add(chooseButton);
        buttonPanel.add(watermarkTextField);
        buttonPanel.add(exportButton);
        frame.add(buttonPanel, BorderLayout.NORTH);
        frame.add(fileLabel, BorderLayout.CENTER); // 将标签放置在按钮下方
        frame.setVisible(true);
    }

    private static void saveProperties(String key, String value) {
        properties.setProperty(key, value);
        try (OutputStream output = new FileOutputStream(CONFIG_FILE)) {
            properties.store(output, null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void loadProperties() {
        try (InputStream input = new FileInputStream(CONFIG_FILE)) {
            properties.load(input);
        } catch (IOException ex) {
            // 如果配置文件不存在或无法读取，则忽略异常
        }
    }

    public static void doPPT2007toImage(File pptFile, String imgFile, String watermark) {
        FileInputStream is = null;
        try {
            is = new FileInputStream(pptFile);

            XMLSlideShow xmlSlideShow = new XMLSlideShow(is);
            is.close();
            // 获取大小
            Dimension pgsize = xmlSlideShow.getPageSize();
            // 获取幻灯片
            List<XSLFSlide> slides = xmlSlideShow.getSlides();

            // 创建一个长图像
            int totalHeight = pgsize.height * slides.size() + (slides.size()-1) * 10; // 加上所有分隔符的高度
            BufferedImage longImg = new BufferedImage(pgsize.width, totalHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = longImg.createGraphics();

            int offsetY = 0;
            for (int i = 0; i < slides.size(); i++) {
                // 解决乱码问题
                XSLFSlide slide = slides.get(i);
                List<XSLFShape> shapes1 = slide.getShapes();
                for (XSLFShape shape : shapes1) {
                    if (shape instanceof XSLFTextShape) {
                        XSLFTextShape sh = (XSLFTextShape) shape;
                        List<XSLFTextParagraph> textParagraphs = sh.getTextParagraphs();
                        for (XSLFTextParagraph xslfTextParagraph : textParagraphs) {
                            List<XSLFTextRun> textRuns = xslfTextParagraph.getTextRuns();
                            for (XSLFTextRun xslfTextRun : textRuns) {
                                xslfTextRun.setFontFamily("宋体");
                            }
                        }
                    }
                }
                // 根据幻灯片大小生成图片
                BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
                Graphics2D slideGraphics = img.createGraphics();
                slideGraphics.setPaint(Color.white);
                slideGraphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
                slide.draw(slideGraphics);
                // 拷贝到长图像上
                g2d.drawImage(img, 0, offsetY, null);

                // 如果不是最后一个幻灯片，则绘制分隔线
                if (i < slides.size() - 1) {
                    g2d.setPaint(Color.WHITE); // 设置颜色为白色
                    g2d.fillRect(0, offsetY + pgsize.height, pgsize.width, 10); // 绘制10px高的分隔线
                    offsetY += 10; // 增加分隔线的高度
                }
                offsetY += pgsize.height;
            }

            // 添加水印
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); // 设置透明度
            g2d.setColor(new Color(128, 128, 128, 128)); // 设置灰色
            g2d.setFont(new Font("宋体", Font.BOLD, 16));
            Map<TextAttribute, Float> attributes = new HashMap<>();
            attributes.put(TextAttribute.SIZE, 50f);
            g2d.setFont(g2d.getFont().deriveFont(attributes));
            // 计算水印的位置
            int xStep = 300; // 水印之间的水平间距
            int yStep = 300; // 水印之间的垂直间距
            for (int y = 0; y < totalHeight; y += yStep) {
                for (int x = 0; x < pgsize.width; x += xStep) {
                    g2d.drawString(watermark, x, y); // 使用从输入框获取的水印内容
                }
            }
            // 保存长图像
            File jpegFile = new File(imgFile + "/展示图.jpeg");
            ImageIO.write(longImg, "jpeg", jpegFile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
